/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * UserComplexImport.java
 *
 * Created on Jan 10, 2011, 3:25:54 PM
 */

package Relationship.Complex.Importing;

import Relationship.Complex.Creation.ComplexRelationshipInfo;
import Relationship.Complex.Creation.VerifyRegexWithClasses;
import Relationship.Complex.DataTypes.ComplexRel;
import Relationship.Complex.DataTypes.ComplexRelImportReturn;
import Relationship.Importing.iFinished;
import ResultEditor.Annotations.Annotation;
import ResultEditor.Annotations.ComplexRelationship;
import ResultEditor.Annotations.Depot;
import java.awt.Color;
import java.util.ArrayList;
import java.util.Collection;
import java.util.TreeSet;
import java.util.Vector;

/**
 *
 * @author Kyle
 */
public class UserComplexImport extends javax.swing.JFrame {
    //<editor-fold defaultstate="collapsed" desc="Member Variables">
    private ArrayList<ComplexRelImportReturn> unknownRels = new ArrayList<ComplexRelImportReturn>();
    private int position;
    private iFinished caller;
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="Constructor">
    /**
     * The constructor for a Complex Relationship importing gui.
     * @param guiX - the X position of the calling GUI.
     * @param guiY - the Y position of the calling GUI.
     * @param width - the Width of the calling GUI.
     * @param height - the Height of the calling GUI.
     * @param toUse - the Collection of Complex Relationships that are being imported.
     */
    public UserComplexImport(int guiX, int guiY, int width, int height,Collection<ComplexRelImportReturn> toUse, iFinished caller)
    {
        this.caller = caller;
        position = 0;
        unknownRels.addAll(toUse);
        //Init gui components ***DO NOT ATTEMPT TO USE COMPONENTS BEFORE THIS LINE!!!*****
        initComponents();
        //Popuolate gui components with initial information
        updateInfo();
        setButtonsBasedOnValidity();
        if(unknownRels.size() ==1)
            next.setText("Done");

        //set dialog location to center of parent GUI.
        int x = 0;
        int y = 0;

        int eHOSTx = guiX; int eHOSTy = guiY;
        x = eHOSTx + (int)((width-this.getWidth())/2);
        y = eHOSTy + (int)((height-this.getHeight())/2);

        this.setLocation(x, y);
    }
    //</editor-fold>

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        Head = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        jTextArea1 = new javax.swing.JTextArea();
        End = new javax.swing.JPanel();
        jPanel3 = new javax.swing.JPanel();
        jPanel9 = new javax.swing.JPanel();
        BodyTitle = new javax.swing.JLabel();
        nameLabel = new javax.swing.JTextField();
        jPanel6 = new javax.swing.JPanel();
        userRegex = new javax.swing.JTextField();
        jLabel1 = new javax.swing.JLabel();
        jButton2 = new javax.swing.JButton();
        jPanel4 = new javax.swing.JPanel();
        jPanel5 = new javax.swing.JPanel();
        jPanel8 = new javax.swing.JPanel();
        jButton1 = new javax.swing.JButton();
        jButton3 = new javax.swing.JButton();
        jPanel7 = new javax.swing.JPanel();
        skipAll = new javax.swing.JButton();
        skip = new javax.swing.JButton();
        next = new javax.swing.JButton();
        Body = new javax.swing.JPanel();
        jPanel1 = new javax.swing.JPanel();
        jLabel2 = new javax.swing.JLabel();
        jPanel2 = new javax.swing.JPanel();
        jScrollPane2 = new javax.swing.JScrollPane();
        importedInfoList = new javax.swing.JList();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setTitle("Relationship Importer");
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosed(java.awt.event.WindowEvent evt) {
                formWindowClosed(evt);
            }
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
        });

        Head.setLayout(new java.awt.BorderLayout());

        jScrollPane1.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);

        jTextArea1.setColumns(20);
        jTextArea1.setEditable(false);
        jTextArea1.setLineWrap(true);
        jTextArea1.setRows(5);
        jTextArea1.setText("eHOST has imported an unknown relationship.  Please input the regular expression that matches the allowed classes for this relationship.  If the relationship name is unique and the regular expression is unique and valid the save button will activate.\n");
        jTextArea1.setWrapStyleWord(true);
        jScrollPane1.setViewportView(jTextArea1);

        Head.add(jScrollPane1, java.awt.BorderLayout.CENTER);

        getContentPane().add(Head, java.awt.BorderLayout.PAGE_START);

        End.setLayout(new java.awt.BorderLayout());

        jPanel3.setLayout(new java.awt.GridLayout(4, 1, 10, 10));

        jPanel9.setLayout(new java.awt.BorderLayout());

        BodyTitle.setText("Imported Name:");
        jPanel9.add(BodyTitle, java.awt.BorderLayout.LINE_START);

        nameLabel.setToolTipText("<html>\nRed: The relationship name is already in the schema.<br/>\nWhite: The relationship name is new to the schema.\n</html>");
        nameLabel.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                nameLabelActionPerformed(evt);
            }
        });
        nameLabel.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyReleased(java.awt.event.KeyEvent evt) {
                nameLabelKeyReleased(evt);
            }
        });
        jPanel9.add(nameLabel, java.awt.BorderLayout.CENTER);

        jPanel3.add(jPanel9);

        jPanel6.setLayout(new java.awt.BorderLayout());

        userRegex.setToolTipText("<html>\nWhite: Regular expression is good and matches all Imported Relationships.<br/>\nYellow: Valid regular expression, but doesn't contain all imported relationships.<br/>\nRed: Regular expression does not fit within guidelines.\n</html>");
        userRegex.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                userRegexActionPerformed(evt);
            }
        });
        userRegex.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyReleased(java.awt.event.KeyEvent evt) {
                userRegexKeyReleased(evt);
            }
        });
        jPanel6.add(userRegex, java.awt.BorderLayout.CENTER);

        jLabel1.setText("   Actual Regex:");
        jPanel6.add(jLabel1, java.awt.BorderLayout.LINE_START);

        jButton2.setText("Help");
        jButton2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton2ActionPerformed(evt);
            }
        });
        jPanel6.add(jButton2, java.awt.BorderLayout.LINE_END);

        jPanel3.add(jPanel6);

        jPanel4.setLayout(new java.awt.GridLayout(1, 3));

        jPanel5.setLayout(new java.awt.BorderLayout());
        jPanel4.add(jPanel5);

        jPanel8.setLayout(new java.awt.BorderLayout());

        jButton1.setText("Delete All Relationships");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });
        jPanel8.add(jButton1, java.awt.BorderLayout.CENTER);

        jPanel4.add(jPanel8);

        jButton3.setText("Delete Current Relationship");
        jButton3.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton3ActionPerformed(evt);
            }
        });
        jPanel4.add(jButton3);

        jPanel3.add(jPanel4);

        jPanel7.setLayout(new java.awt.GridLayout(1, 0));

        skipAll.setText("Skip All");
        skipAll.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                skipAllActionPerformed(evt);
            }
        });
        jPanel7.add(skipAll);

        skip.setText("Skip");
        skip.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                skipActionPerformed(evt);
            }
        });
        jPanel7.add(skip);

        next.setText("Save & Continue");
        next.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                nextActionPerformed(evt);
            }
        });
        jPanel7.add(next);

        jPanel3.add(jPanel7);

        End.add(jPanel3, java.awt.BorderLayout.CENTER);

        getContentPane().add(End, java.awt.BorderLayout.PAGE_END);

        Body.setLayout(new java.awt.BorderLayout());

        jPanel1.setLayout(new java.awt.GridLayout(1, 1));

        jLabel2.setText("Imported Regular Expressions:");
        jPanel1.add(jLabel2);

        Body.add(jPanel1, java.awt.BorderLayout.PAGE_START);

        jPanel2.setLayout(new java.awt.BorderLayout());

        jScrollPane2.setViewportView(importedInfoList);

        jPanel2.add(jScrollPane2, java.awt.BorderLayout.CENTER);

        Body.add(jPanel2, java.awt.BorderLayout.CENTER);

        getContentPane().add(Body, java.awt.BorderLayout.CENTER);

        pack();
    }// </editor-fold>//GEN-END:initComponents

    //<editor-fold defaultstate="collapsed" desc="Event Handling Methods">
    private void userRegexActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_userRegexActionPerformed
    {//GEN-HEADEREND:event_userRegexActionPerformed
        
    }//GEN-LAST:event_userRegexActionPerformed

    private void skipActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_skipActionPerformed
    {//GEN-HEADEREND:event_skipActionPerformed
        movePosition(true);
    }//GEN-LAST:event_skipActionPerformed

    private void skipAllActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_skipAllActionPerformed
    {//GEN-HEADEREND:event_skipAllActionPerformed
        caller.finished();
        this.dispose();
    }//GEN-LAST:event_skipAllActionPerformed

    private void userRegexKeyReleased(java.awt.event.KeyEvent evt)//GEN-FIRST:event_userRegexKeyReleased
    {//GEN-HEADEREND:event_userRegexKeyReleased
        setButtonsBasedOnValidity();
    }//GEN-LAST:event_userRegexKeyReleased

    private void nextActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_nextActionPerformed
    {//GEN-HEADEREND:event_nextActionPerformed
        makeNewComplexRel();
        movePosition(true);
}//GEN-LAST:event_nextActionPerformed

    private void nameLabelKeyReleased(java.awt.event.KeyEvent evt)//GEN-FIRST:event_nameLabelKeyReleased
    {//GEN-HEADEREND:event_nameLabelKeyReleased
        setButtonsBasedOnValidity();
    }//GEN-LAST:event_nameLabelKeyReleased

    private void jButton3ActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_jButton3ActionPerformed
    {//GEN-HEADEREND:event_jButton3ActionPerformed
        Depot depot = new Depot();
        //Delete all unknown relatinoships/attributes
        for(Annotation annotation: depot.getAllAnnotations())
        {
            //Annotation is unverified if it is still new
            if(!annotation.isVerified())
            {
                //Make sure we have some ComplexRelationships before trying to delete them
                if(annotation.ComplexRelationships != null)
                {
                    //Delete unknown relationships
                    for(int i = 0; i< annotation.ComplexRelationships.size(); i++)
                    {
                        ComplexRelationship rel = annotation.ComplexRelationships.get(i);

                        //If a selected relatinoship has the same name as the annotation then
                        //delete the relationship from the annotation
                        ComplexRelImportReturn newOnes = unknownRels.get(position);
                        {
                            if(newOnes.getName().equals(rel.getMentionSlotID()))
                            {
                                //TODO: Only delete relationships that match regex being delted.
                                annotation.ComplexRelationships.remove(i);
                                i--;
                            }
                        }
                    }
                }
            }
        }
        movePosition(true);
    }//GEN-LAST:event_jButton3ActionPerformed

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_jButton1ActionPerformed
    {//GEN-HEADEREND:event_jButton1ActionPerformed
        Depot depot = new Depot();
        //Delete all unknown relatinoships/attributes
        for(Annotation annotation: depot.getAllAnnotations())
        {
            //Annotation is unverified if it is still new
            if(!annotation.isVerified())
            {
                //Make sure we have some ComplexRelationships before trying to delete them
                if(annotation.ComplexRelationships != null)
                {
                    //Delete unknown relationships
                    for(int i = 0; i< annotation.ComplexRelationships.size(); i++)
                    {
                        ComplexRelationship rel = annotation.ComplexRelationships.get(i);

                        //If a selected relatinoship has the same name as the annotation then
                        //delete the relationship from the annotation
                        for(ComplexRelImportReturn newOnes: unknownRels)
                        {
                            if(newOnes.getName().equals(rel.getMentionSlotID()))
                            {
                                //TODO: Only delete relationships that match regex being delted.
                                annotation.ComplexRelationships.remove(i);
                                i--;
                            }
                        }
                    }
                }
            }
        }
        caller.finished();
        this.dispose();
    }//GEN-LAST:event_jButton1ActionPerformed

    private void formWindowClosing(java.awt.event.WindowEvent evt)//GEN-FIRST:event_formWindowClosing
    {//GEN-HEADEREND:event_formWindowClosing
        
    }//GEN-LAST:event_formWindowClosing

    private void formWindowClosed(java.awt.event.WindowEvent evt)//GEN-FIRST:event_formWindowClosed
    {//GEN-HEADEREND:event_formWindowClosed
        
    }//GEN-LAST:event_formWindowClosed

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed
        ComplexRelationshipInfo info = new ComplexRelationshipInfo(this);
        info.setVisible(true);
    }//GEN-LAST:event_jButton2ActionPerformed

    private void nameLabelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nameLabelActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_nameLabelActionPerformed
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="Private Methods">
    /**
     * This method will update the State of the gui based on the values in the
     * text boxes for the Name and the Regular Expression for a relationship.
     * The background color of the text boxes will be red if the value is not
     * valid.
     */
    private void setButtonsBasedOnValidity()
    {
        //Verify that the regular expression and name that the user entered is valid
        boolean goodRegex = VerifyRegexWithClasses.CheckValidRegex(userRegex.getText()) && !userRegex.getText().equals("");
        boolean goodName = !nameLabel.getText().equals("");

        //Verify that the relationship name and regular expression are unique to the schema.
        boolean nameExists = env.Parameters.ComplexRelationshipNames.checkNameExists(nameLabel.getText());
        boolean regexExists = env.Parameters.ComplexRelationshipNames.checkRegexExists(userRegex.getText());

        boolean regexMatchesAllClasses = this.checkRegexHoldsAll(userRegex.getText());

        //Concatenate boolean results to be more useful
        boolean regexReady = goodRegex && !regexExists;
        boolean nameReady = goodName && !nameExists;
        boolean everythingReady = nameReady & regexReady;

        //If everything is good enable the 'next' button and set background color
        //of regex bar to green.
        if(everythingReady)
        {
            if(!regexMatchesAllClasses)
            {
                userRegex.setBackground(new Color(255,255,0));
            }
            else
            {
                userRegex.setBackground(new Color(255,255,255));
            }
            nameLabel.setBackground( new Color(255,255,255));
            next.setEnabled(true);
        }

        //Regex is bad or already exists in schema...
        else
        {
            if(!regexReady)
            {
                userRegex.setBackground(new Color(255,150,150));
            }
            else if (!regexMatchesAllClasses)
            {
                userRegex.setBackground(new Color(255,255,0));
            }
            else
                userRegex.setBackground(new Color(255,255,255));
            if(!nameReady)
                nameLabel.setBackground(new Color(255,150,150));
            else
                nameLabel.setBackground(new Color(255,255,255));
             
            next.setEnabled(false);
        }
    }
    private boolean checkRegexHoldsAll(String regex)
    {
        return VerifyRegexWithClasses.checkRegexFitsAll(regex,this.unknownRels.get(position).getClassesConcatenated());
    }
    /**
     * Make a new Complex Relationship with the current GUI information.
     */
    private void makeNewComplexRel()
    {
         ComplexRel rel = new ComplexRel(nameLabel.getText(), userRegex.getText());
         env.Parameters.ComplexRelationshipNames.add(rel);
    }
    /**
     * Increment or decrement the relationship we're currently looking at.
     * @param forward - true if incrementing, false if decrementing.
     */
    private void movePosition(boolean forward)
    {
        //Assume we're not going to change anything...
        boolean changed = false;

        //incrementing/moving forwards
        if(forward)
        {
            if(position == unknownRels.size() -1)
            {
                caller.finished();
                 this.dispose();
            }

            else if(position == unknownRels.size() -2)
            {
                position++;
                changed =true;
                next.setText("Done");
            }
            else
            {
                changed = true;
                position++;
            }
        }
        //Decrementing/moving backwards
        else
        {
            if(position >= 1)
            {
                position --;
                changed = true;
            }
            else
            {
                //Do nothing... can't move backwards anymore.
            }
        }
        if(changed)
        {
            userRegex.setText("");
        }
        updateInfo();
        setButtonsBasedOnValidity();
    }
    /**
     * Update the info in the GUI based on the position in the list of imported
     * relationships.
     */
    private void updateInfo()
    {

        nameLabel.setText(unknownRels.get(position).getName());
        Vector<String> toSet = new Vector<String>();

        for(String s: unknownRels.get(position).getRegex())
        {
            toSet.add(s);
        }
        importedInfoList.setListData(toSet);
        setButtonsBasedOnValidity();
    }
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="GUI Member Variables">
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel Body;
    private javax.swing.JLabel BodyTitle;
    private javax.swing.JPanel End;
    private javax.swing.JPanel Head;
    private javax.swing.JList importedInfoList;
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JButton jButton3;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JPanel jPanel4;
    private javax.swing.JPanel jPanel5;
    private javax.swing.JPanel jPanel6;
    private javax.swing.JPanel jPanel7;
    private javax.swing.JPanel jPanel8;
    private javax.swing.JPanel jPanel9;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JTextArea jTextArea1;
    private javax.swing.JTextField nameLabel;
    private javax.swing.JButton next;
    private javax.swing.JButton skip;
    private javax.swing.JButton skipAll;
    private javax.swing.JTextField userRegex;
    // End of variables declaration//GEN-END:variables
    //</editor-fold>
}
